package com.example.interview.parent_son2;

import com.example.interview.parent_son.TreeNode;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

public class ITree2Impl implements ITree2 {
//    public ITreeImpl(List<ITreeNode> list){
//        initTreeNodeMap(list);
//        initTreeNodeList();
//    }
    private HashMap<String, TreeNode> treeNodesMap = new HashMap<String, TreeNode>();
    private List<TreeNode> treeNodesList = new ArrayList<TreeNode>();

    //查询所有tree + 带有searched功能的  搜索后展示 http://localhost:2080/system/dept/t14
//    @GetMapping("/t14")   // 为了测试方便： .antMatchers("/system/dept/**").anonymous()
    @Override
    public List<SysDept> t14c(SysDept dept) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, NoSuchFieldException {
        List<SysDept> depts = this.selectDeptList(dept);
        List<SysDept> sysDepts = useListRecordToTreeByKeywords(depts, "", "deptName");
        return sysDepts;
    }

    //查询所有tree 默认展示
//    @GetMapping("/t13")
    public List<SysDept> t13c(SysDept dept)
    {
        List<SysDept> depts = this.selectDeptList(dept);
        return useListRecordToTree(depts);
    }
    /**
     * 说明方法描述：将list转为树tree结构
     *
     * @param allRrecords
     * @return
     * @time 2016年5月10日 下午6:00:35
     * @author yangdong
     */
    public List<SysDept> useListRecordToTree(List<SysDept> allRrecords) {

        List<SysDept> listParentRecord = new ArrayList<SysDept>();
        List<SysDept> listNotParentRecord = new ArrayList<SysDept>();
        // 第一步：遍历allRrecords保存所有数据的uuid用于判断是不是根节点
        Map<String, String> mapAllUuid = new HashMap<String, String>();
        Map<String, SysDept> allRecordMap = new HashMap<String, SysDept>();
        for (SysDept record : allRrecords) {
            mapAllUuid.put(record.getDeptId().toString(), record.getDeptId().toString());
            allRecordMap.put(record.getDeptId().toString(), record);
        }
        // 第二步：遍历allRrecords找出所有的根节点和非根节点
        if (allRrecords != null && allRrecords.size() > 0) {
            for (SysDept record : allRrecords) {
                if (StringUtils.isBlank(record.getParentId().toString())
                        || !mapAllUuid.containsKey(record.getParentId().toString())) {
                    listParentRecord.add(record);
                } else {
                    listNotParentRecord.add(record);
                }
            }
        }

        // 第三步： 递归获取所有子节点
        if (listParentRecord.size() > 0) {
            for (SysDept parentLevelBeans : listParentRecord) {
                // 添加所有子级
//                record.set("childs", this.getTreeChildRecord(listNotParentRecord, record.getStr("uuid")));
                parentLevelBeans.setChildren(this.getTreeChildRecord(listNotParentRecord, parentLevelBeans.getDeptId().toString()));
            }
        }
        return listParentRecord;
    }

    /**
     * 说明方法描述：递归查询子节点
     *
     * @param allChildList 子节点
     * @param oneParentId 父节点id
     * @return
     * @time 2016年5月10日 下午3:29:35
     * @author yangdong
     */
    private List<SysDept> getTreeChildRecord(List<SysDept> allChildList, String oneParentId) {
        List<SysDept> childsOfOneParent = new ArrayList<SysDept>();
        List<SysDept> childsNotOfOneParent = new ArrayList<SysDept>();
        // 遍历tmpList，找出所有的根节点和非根节点
        if (allChildList != null && allChildList.size() > 0) {
            for (SysDept childBeans : allChildList) {
                // 对比找出父节点
                if (StringUtils.equals(childBeans.getParentId().toString(), oneParentId)) {
                    childsOfOneParent.add(childBeans);
                } else {
                    childsNotOfOneParent.add(childBeans);
                }
            }
        }
        // 查询子节点
        if (childsOfOneParent.size() > 0) {
            for (SysDept record : childsOfOneParent) {
                // 递归查询子节点
//                record.set("childs", getTreeChildRecord(listNotParentRecord, record.getStr("uuid")));
                record.setChildren(getTreeChildRecord(childsNotOfOneParent, record.getDeptId().toString()));
            }
        }
        return childsOfOneParent;
    }


    //init数据
    public List<SysDept> selectDeptList(SysDept dept) {
        ArrayList<SysDept> d = new ArrayList<>();
        d.add(new SysDept(100L, 0L,   "0", 			"若依科技", 	"0", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        d.add(new SysDept(101L, 100L, "0,100", 		"深圳总公司", 	"1", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        d.add(new SysDept(102L, 100L, "0,100", 		"长沙分公司", 	"2", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        d.add(new SysDept(103L, 101L, "0,100,101", 	"研发部门", 	"1", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        d.add(new SysDept(104L, 101L, "0,100,101", 	"市场部门", 	"2", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        d.add(new SysDept(105L, 101L, "0,100,101", 	"测试部门", 	"3", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        d.add(new SysDept(106L, 101L, "0,100,101", 	"财务部门", 	"4", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        d.add(new SysDept(107L, 101L, "0,100,101", 	"运维部门", 	"5", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        d.add(new SysDept(108L, 102L, "0,100,102", 	"市场部门", 	"1", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        d.add(new SysDept(109L, 102L, "0,100,102", 	"财务部门", 	"2", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:34", "", null));
        return d;
    }
    static ArrayList<SysDept> deptArrayList = new ArrayList<>();
    static {
        deptArrayList.add(new SysDept(100L, 0L,   "0", 			"若依科技", 	"0", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        deptArrayList.add(new SysDept(101L, 100L, "0,100", 		"深圳总公司", 	"1", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        deptArrayList.add(new SysDept(102L, 100L, "0,100", 		"长沙分公司", 	"2", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        deptArrayList.add(new SysDept(103L, 101L, "0,100,101", 	"研发部门", 	"1", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        deptArrayList.add(new SysDept(104L, 101L, "0,100,101", 	"市场部门", 	"2", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        deptArrayList.add(new SysDept(105L, 101L, "0,100,101", 	"测试部门", 	"3", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        deptArrayList.add(new SysDept(106L, 101L, "0,100,101", 	"财务部门", 	"4", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        deptArrayList.add(new SysDept(107L, 101L, "0,100,101", 	"运维部门", 	"5", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        deptArrayList.add(new SysDept(108L, 102L, "0,100,102", 	"市场部门", 	"1", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:33", "", null));
        deptArrayList.add(new SysDept(109L, 102L, "0,100,102", 	"财务部门", 	"2", "若依", "15888888888", "ry@qq.com", "0", "0", "admin", "2021-04-18 13:48:34", "", null));
    }

    @Override
    public SysDept selectDeptById(long l) {
        for (SysDept de : deptArrayList) {
            if (de.getDeptId() == l) {
                return de;
            }
        }
        return null;
    }

    /**
     * 说明方法描述：使list转换为树并根据关键字和节点名称过滤
     *
     * @param allRecords 所有节点
     * @param keywords 要过滤的关键字
     * @param filterFields 要过滤的字段
     * @return
     * @time 2016年5月19日 下午3:27:32
     * @author yangdong
     */
    @Override
    public List<SysDept> useListRecordToTreeByKeywords(List<SysDept> allRecords, String keywords, String... filterFields) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        List<SysDept> searchLeafList = new ArrayList<SysDept>();
        Map<String, SysDept> allRecordMap = new HashMap<String, SysDept>();
        for (SysDept record : allRecords) {
            allRecordMap.put(record.getDeptId().toString(), record);
        }
        // 遍历allRrecords找出所有的nodeName和关键字keywords相关的数据
        if (allRecords != null && allRecords.size() > 0) {
            if (filterFields.length > 1) {
                for (SysDept record : allRecords) {
                    for (String field : filterFields) {

                        Class clazz1= SysDept.class;
                        Field field1 = clazz1.getDeclaredField("deptName");
                        field1.setAccessible(true);
                        Object object = field1.get(record);//获取当前字段的值
                        // 比较
//                        if (record.getStr(field).toLowerCase().indexOf(keywords.toLowerCase()) != -1) {
                        if (null != object && object.toString().toLowerCase().indexOf(keywords.toLowerCase()) != -1) {
                            searchLeafList.add(record);
                        }
                    }
                }
            } else {
                for (SysDept record : allRecords) {

                    Class clazz1= SysDept.class;
                    Field field1 = clazz1.getDeclaredField("deptName");
                    field1.setAccessible(true);
                    Object object = field1.get(record);//获取当前字段的值

//                    String fieldName="deptName";
//                    String	methodName="get"+
//                            fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
//                    Method method = clazz1.getMethod(methodName);
//                    Object object = method.invoke(record);
                    // 比较
//                    if (record.getStr(filterFields[0]).toLowerCase().indexOf(keywords.toLowerCase()) != -1) {
                    if (null != object && object.toString().toLowerCase().indexOf(keywords.toLowerCase()) != -1) {
                        searchLeafList.add(record);
                    }
                }
            }
        }

        //1.获取search后的 斜杠拼接的name
        List<SysDept> list42 = new LinkedList<>();
        Map<String, List<SysDept>> map14 = new HashMap<>();
        for (SysDept searchLeaf : searchLeafList) {
            List<SysDept> newBean = Arrays.asList(searchLeaf);//保证每次传入的size为1
            List<SysDept> list41 = this.getSelfAndTheirParentRecord(newBean, new ArrayList<SysDept>(),
                    new HashMap<String, SysDept>(), allRecordMap);
            list41 =  list41.stream().filter(a -> a.getDeptId() != 100L).sorted(Comparator.comparing(SysDept::getDeptId)).collect(Collectors.toList());
            StringBuilder builder = new StringBuilder();
            for (SysDept t41 :  list41 ) {
                builder.append(t41.getDeptName());
                builder.append("/");
            }
            searchLeaf.setDeptName(builder.toString());
            list42.add(searchLeaf);

            map14.put(searchLeaf.getDeptId().toString(), list41);
        }
        return this.useListRecordToTree42(list42);

        //2.获取search后的所有层级tree
//        // 查找过滤出来的节点和他们的父节点
//        searchLeafList = this.getSelfAndTheirParentRecord(searchLeafList, new ArrayList<SysDept>(),
//                new HashMap<String, SysDept>(), allRecordMap );
//
//        // 将过滤出来的数据变成树tree结构
//        searchLeafList = this.useListRecordToTree(searchLeafList);
//        return searchLeafList;
    }

    @Override
    public List<SysDept> useListRecordToTree42(List<SysDept> allRrecords) {
        SysDept deptRoot = this.selectDeptById(100L);
        deptRoot.setChildren(allRrecords);
        List<SysDept> sysDepts = Arrays.asList(deptRoot);
        return sysDepts;
    }



    /**
     * 说明方法描述：递归找出本节点和他们的父节点
     *
     * @param searchLeafList 根据关键字过滤出来的相关节点的父节点
     * @param resultList 返回的过滤出来的节点     new ArrayList<SysDept>()
     * @param filterRecordMap 已经过滤出来的节点  new HashMap<String, SysDept>()
     * @param allRecordMap 所有节点map  Map<String, SysDept>
     * @return
     * @time 2016年5月19日 上午9:53:56
     * @author yangdong
     */
    @Override
    public List<SysDept> getSelfAndTheirParentRecord(List<SysDept> searchLeafList, List<SysDept> resultList,
                                                     Map<String, SysDept> filterRecordMap,
                                                     Map<String, SysDept> allRecordMap
    ) {
        // 当父节点为null或者节点数量为0时返回结果，退出递归
        if (searchLeafList == null || searchLeafList.size() == 0) {
            return resultList;
        }
        // 重新创建父节点集合
        List<SysDept> listParentRecord = new ArrayList<>();
        // 遍历 过滤到的 目标节点对象
        for (SysDept searchLeaf : searchLeafList) {
            String id_dept = searchLeaf.getDeptId().toString();     //本节点
            String id_parent = searchLeaf.getParentId().toString(); //本节点的父节点
            // 如果已经过滤出来的节点不存在则添加到list中
            if (!filterRecordMap.containsKey(id_dept)) { //唯一性过滤
                filterRecordMap.put(id_dept, searchLeaf);// 添加到已过滤的map中
                listParentRecord.add(searchLeaf);// 添加到父节点中
//                allRecordMap.remove(id_dept);// 移除集合中相应的元素 为了效率
                resultList.add(searchLeaf);// 添加到结果集中
            }

            // 找出 本节点的父节点 并添加到listParentRecord父节点集合中，并移除集合中相应的元素
            if (StringUtils.isNotBlank(id_parent)) {
                SysDept parentRecord = allRecordMap.get(id_parent);
                if (parentRecord != null) {
                    listParentRecord.add(parentRecord);
//                    allRecordMap.remove(id_parent);
                }
            }

        }
        // 递归调用
        getSelfAndTheirParentRecord(listParentRecord, resultList, filterRecordMap, allRecordMap);
        return resultList;
    }

}
